#include "sensor_aggregator.h"
#include <stdio.h>
#include <math.h>
#include <string.h>

#define SAFE_DIVISION(numerator, denominator) \
    ((denominator == 0) ? 0 : ((numerator) / (denominator)))

void agg_init(SensorAggregator* agg, uint32_t interval_ms) {
    memset(agg, 0, sizeof(SensorAggregator));
    agg->window_interval = interval_ms;
    agg->window_start = osal_gettime();
    
    for(int i=0; i<SENSOR_TYPE_COUNT; i++){
        agg->metrics[i].max = -INFINITY;
        agg->metrics[i].min = INFINITY;
    }
}

void agg_update(SensorAggregator* agg, SensorType type, float value, uint32_t timestamp) {
    SensorMetric* metric = &agg->metrics[type];
    
    // 更新统计值
    metric->max = fmaxf(metric->max, value);
    metric->min = fminf(metric->min, value);
    metric->sum += value;
    metric->count++;
    metric->last_update = timestamp;
}

int agg_check_window(SensorAggregator* agg, uint32_t current_time) {
    return (current_time - agg->window_start) >= agg->window_interval;
}

const char* agg_generate_report(SensorAggregator* agg, char* buffer, size_t buf_size) {
    static const char* sensor_names[] = {
        "Temperature", "Humidity", "Light", "Soil"
    };
    
    char* ptr = buffer;
    size_t remaining = buf_size;
    
    for(int i=0; i<SENSOR_TYPE_COUNT; i++){
        const SensorMetric* m = &agg->metrics[i];
        
        if(m->count == 0) continue;  // 无数据不报告
        
        float avg = SAFE_DIVISION(m->sum, m->count);
        
        int written = snprintf(ptr, remaining,
            "[%s] MAX=%.1f MIN=%.1f AVG=%.1f | ",
            sensor_names[i],
            m->max,
            m->min,
            avg
        );
        
        if(written >= remaining) break;
        ptr += written;
        remaining -= written;
    }
    
    if(ptr == buffer) {  // 无有效数据
        strncpy(buffer, "No sensor data", buf_size);
    } else {
        ptr[-3] = '\0';  // 移除最后的"| "分隔符
    }
    
    return buffer;
}

void agg_reset(SensorAggregator* agg) {
    for(int i=0; i<SENSOR_TYPE_COUNT; i++){
        agg->metrics[i].max = -INFINITY;
        agg->metrics[i].min = INFINITY;
        agg->metrics[i].sum = 0;
        agg->metrics[i].count = 0;
    }
    agg->window_start = osal_gettime();
}